/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/** *****************************************************************************************************
 *  \file     Wes.h
 *  \brief    This file contains interface header for Wes driver
 *
 * <table>
 * <tr><th>Date           <th>Version
 * <tr><td>2024/12/13     <td>1.0.0
 * </table>
 *******************************************************************************************************/
#ifndef WES_H
#define WES_H
/********************************************************************************************************
 *                                      Include header files
 *******************************************************************************************************/
#include <lld_platform.h>

/********************************************************************************************************
 *                                 Global Macro definition
 *******************************************************************************************************/
#if defined(CFG_PLATFORM_MCAL)
#define WES_E_ERROR(code) (code)
#elif defined(CFG_PLATFORM_SSDK)
#define WES_E_ERROR(code) SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_WES, (code))
#else
#error "Undefined macros CFG_PLATFORM_MCAL or CFG_PLATFORM_SSDK"
#endif /** #if defined (CFG_PLATFORM_MCAL) */

/********************************************************************************************************
 *                                 Global Macro definition
 *******************************************************************************************************/

/** \brief WES FUSA Interrupt Status */

/**< WES lockstep compare error status */
#define WES_FUSA_LOCKSTEP_COMPARE_ERROR (0x1U << 31U)

/**< WES SADC handshake timeout or TID check error status */
#define WES_FUSA_SADC_HANDSHAKE_ERROR (0x1U << 30U)

/**< WES selftest mode error status */
#define WES_FUSA_SELFTEST_MODE_ERROR (0x1U << 29U)

/**< WES test mode check error status */
#define WES_FUSA_TEST_MODE_ERROR (0x1U << 28U)

/**< WES timer1 clock monitor error status */
#define WES_FUSA_TIMER1_CLK_MON_ERROR (0x1U << 27U)

/**< WES timer0 clock monitor error status */
#define WES_FUSA_TIMER0_CLK_MON_ERROR (0x1U << 26U)

/**< WES timer1 pwm2 and pwm3 check error status */
#define WES_FUSA_TIMER1_PWM23_CHECK_ERROR (0x1U << 25U)

/**< WES timer1 pwm0 and pwm1 check error status */
#define WES_FUSA_TIMER1_PWM01_CHECK_ERROR (0x1U << 24U)

/**< WES timer0 pwm2 and pwm3 check error status */
#define WES_FUSA_TIMER0_PWM23_CHECK_ERROR (0x1U << 23U)

/**< WES timer0 pwm0 and pwm1 check error status */
#define WES_FUSA_TIMER0_PWM01_CHECK_ERROR (0x1U << 22U)

/**< WES ASE loopback check error status */
#define WES_FUSA_FUNC_ASE_CHECK_ERROR (0x1U << 21U)

/**< WES DSEL loopback check error status */
#define WES_FUSA_FUNC_DSEL_CHECK_ERROR (0x1U << 20U)

/**< WES DSE loopback check error status */
#define WES_FUSA_FUNC_DSE_CHECK_ERROR (0x1U << 19U)

/**< WES data compare error status */
#define WES_FUSA_FUNC_COMP_CHECK_ERROR (0x1U << 18U)

/**< WES function clock monitor or clock divider ECC error status */
#define WES_FUSA_FUNC_CLK_MON_ERROR (0x1U << 17U)

/**< WES function config error status */
#define WES_FUSA_FUNC_CFG_CHECK_ERROR (0x1U << 16U)

/********************************************************************************************************
 *                                  Global Types definition
 *******************************************************************************************************/

/** \brief WES error codes */
typedef enum {
    /** WES config success */
    WES_OK = 0,
    /** WES config parameters error */
    WES_PARAMETER_ERROR = 1,
    /** WES config wait done timeout */
    WES_SET_UNDONE = 2,
} Wes_ErrorCodeType;

/** \brief WES clock source */
typedef enum {
    /**< Clock from FS24M */
    WES_CLOCK_SOURCE_FS_24M = 0U,
    /**< Clock from FS32K */
    WES_CLOCK_SOURCE_FS_32K = 1U,
    /**< Clock from PAD */
    WES_CLOCK_SOURCE_EXT_CLK = 2U,
} Wes_ClockSourceType;

/** \brief WES sample mode */
typedef enum {
    /**< WES sample mode 0 */
    WES_SAMPLE_MODE_0 = 0U,
    /**< WES sample mode 1 */
    WES_SAMPLE_MODE_1 = 1U,
} Wes_SampleModeType;

/** \brief WES sample timers */
typedef enum {
    /**< WES sample 1 times */
    WES_SAMPLE_1_TIMES = 0U,
    /**< WES sample 2 times */
    WES_SAMPLE_2_TIMES = 1U,
    /**< WES sample 3 times */
    WES_SAMPLE_3_TIMES = 2U,
    /**< WES sample 4 times */
    WES_SAMPLE_4_TIMES = 3U,
} Wes_SampleNumberType;

/** \brief WES trigger type */
typedef enum {
    /**< WES trigger from timer0 */
    WES_SAMPLE_TRIGGER_FROM_TIMER0 = 0U,
    /**< WES trigger from PAD */
    WES_SAMPLE_TRIGGER_FROM_EXTERNAL = 1U,
} Wes_SampleTriggerType;

/** \brief WES trigger index */
typedef enum {
    /**< WES trigger index 0 */
    WES_SAMPLE_TRIGGER_INDEX_0 = 0U,
    /**< WES trigger index 1 */
    WES_SAMPLE_TRIGGER_INDEX_1 = 1U,
    /**< WES trigger index 2 */
    WES_SAMPLE_TRIGGER_INDEX_2 = 2U,
    /**< WES trigger index 3 */
    WES_SAMPLE_TRIGGER_INDEX_3 = 3U,
} Wes_SampleTriggerIndexType;

/** \brief WES work mode */
typedef enum {
    /**< WES normal mode */
    WES_NORMAL_MODE = 0U,
    /**< WES lowpower mode */
    WES_LOW_POWER_MODE = 1U,
} Wes_WorkModeType;

/** \brief WES DSEL port number */
typedef enum {
    /**< WES use 1 DSEL port */
    WES_1_DIGITAL_SELECT_PORT = 0U,
    /**< WES use 2 DSEL port */
    WES_2_DIGITAL_SELECT_PORT = 1U,
    /**< WES use 3 DSEL port */
    WES_3_DIGITAL_SELECT_PORT = 2U,
    /**< WES use 4 DSEL port */
    WES_4_DIGITAL_SELECT_PORT = 3U,
    /**< WES use 5 DSEL port */
    WES_5_DIGITAL_SELECT_PORT = 4U,
    /**< WES use 6 DSEL port */
    WES_6_DIGITAL_SELECT_PORT = 5U,
    /**< WES use 7 DSEL port */
    WES_7_DIGITAL_SELECT_PORT = 6U,
    /**< WES use 8 DSEL port */
    WES_8_DIGITAL_SELECT_PORT = 7U,
} Wes_DigitalSelectPortType;

/** \brief WES timer clock divider */
typedef enum {
    /**< Clock 1 divider */
    WES_TIMER_CLOCK_DIVIDER_1 = 0U,
    /**< Clock 2 divider */
    WES_TIMER_CLOCK_DIVIDER_2 = 1U,
    /**< Clock 4 divider */
    WES_TIMER_CLOCK_DIVIDER_4 = 2U,
    /**< Clock 8 divider */
    WES_TIMER_CLOCK_DIVIDER_8 = 3U,
    /**< Clock 16 divider */
    WES_TIMER_CLOCK_DIVIDER_16 = 4U,
    /**< Clock 32 divider */
    WES_TIMER_CLOCK_DIVIDER_32 = 5U,
    /**< Clock 64 divider */
    WES_TIMER_CLOCK_DIVIDER_64 = 6U,
    /**< Clock 128 divider */
    WES_TIMER_CLOCK_DIVIDER_128 = 7U,
    /**< Clock 256 divider */
    WES_TIMER_CLOCK_DIVIDER_256 = 8U,
    /**< Clock 512 divider */
    WES_TIMER_CLOCK_DIVIDER_512 = 9U,
    /**< Clock 1024 divider */
    WES_TIMER_CLOCK_DIVIDER_1024 = 10U,
    /**< Clock 2048 divider */
    WES_TIMER_CLOCK_DIVIDER_2048 = 11U,
    /**< Clock 4096 divider */
    WES_TIMER_CLOCK_DIVIDER_4096 = 12U,
    /**< Clock 8192 divider */
    WES_TIMER_CLOCK_DIVIDER_8192 = 13U,
    /**< Clock 16384 divider */
    WES_TIMER_CLOCK_DIVIDER_16384 = 14U,
    /**< Clock 32768 divider */
    WES_TIMER_CLOCK_DIVIDER_32768 = 15U,
} Wes_TimerClockDividerType;

/** \brief WES function clock divider */
typedef enum {
    /**< Clock 2 divider */
    WES_FUNC_CLOCK_DIVIDER_2 = 0U,
    /**< Clock 4 divider */
    WES_FUNC_CLOCK_DIVIDER_4 = 1U,
    /**< Clock 8 divider */
    WES_FUNC_CLOCK_DIVIDER_8 = 2U,
    /**< Clock 16 divider */
    WES_FUNC_CLOCK_DIVIDER_16 = 3U,
    /**< Clock 32 divider */
    WES_FUNC_CLOCK_DIVIDER_32 = 4U,
    /**< Clock 64 divider */
    WES_FUNC_CLOCK_DIVIDER_64 = 5U,
    /**< Clock 128 divider */
    WES_FUNC_CLOCK_DIVIDER_128 = 6U,
    /**< Clock 256 divider */
    WES_FUNC_CLOCK_DIVIDER_256 = 7U,
} Wes_FuncClockDividerType;

/** \brief WES digital sample data */
typedef enum {
    /**< WES digital data 0 */
    WES_DIGITAL_SAMPLE_DATA0 = 0U,
    /**< WES digital data 1 */
    WES_DIGITAL_SAMPLE_DATA1 = 1U,
    /**< WES digital data 2 */
    WES_DIGITAL_SAMPLE_DATA2 = 2U,
    /**< WES digital data 3 */
    WES_DIGITAL_SAMPLE_DATA3 = 3U,
    /**< WES digital data 4 */
    WES_DIGITAL_SAMPLE_DATA4 = 4U,
    /**< WES digital data 5 */
    WES_DIGITAL_SAMPLE_DATA5 = 5U,
    /**< WES digital data 6 */
    WES_DIGITAL_SAMPLE_DATA6 = 6U,
    /**< WES digital data 7 */
    WES_DIGITAL_SAMPLE_DATA7 = 7U,
    WES_DIGITAL_SAMPLE_DATA_MAX = 8U,
} Wes_DigitalSampleDataType;

/** \brief WES digital sample data update mode */
typedef enum {
    /**< WES digital sample data update when compare error */
    WES_DIGITAL_SAMPLE_DATA_UPDATE_WHEN_COMPARE_ERROR = 0U,
    /**< WES digital sample data update real time */
    WES_DIGITAL_SAMPLE_DATA_UPDATE_REAL_TIME = 1U,
} Wes_DigitalSampleDataUpdateType;

/** \brief WES timer */
typedef enum {
    /**< WES timer 0 */
    WES_TIMER0 = 0U,
    /**< WES timer 1 */
    WES_TIMER1 = 1U,
    WES_TIMER_MAX = 2U,
} Wes_TimerType;

/** \brief WES timer counter */
typedef enum {
    /**< WES timer counter 0 */
    WES_TIMER_COUNTER0 = 0U,
    /**< WES timer counter 1 */
    WES_TIMER_COUNTER1 = 1U,
    /**< WES timer counter 2 */
    WES_TIMER_COUNTER2 = 2U,
    /**< WES timer counter 3 */
    WES_TIMER_COUNTER3 = 3U,
    WES_TIMER_COUNTER_MAX = 4U,
} Wes_TimerCounterType;

/** \brief WES timer interrupt status */
typedef enum {
    /**< Timer counter 0 compare interrupt */
    WES_TIMER_INT_COMPARE0_STATUS = (0x1U << 16U),
    /**< Timer counter 1 compare interrupt */
    WES_TIMER_INT_COMPARE1_STATUS = (0x1U << 17U),
    /**< Timer counter 2 compare interrupt */
    WES_TIMER_INT_COMPARE2_STATUS = (0x1U << 18U),
    /**< Timer counter 3 compare interrupt */
    WES_TIMER_INT_COMPARE3_STATUS = (0x1U << 19U),
    /**< Timer counter 0 overflow interrupt */
    WES_TIMER_INT_OVERFLOW0_STATUS = (0x1U << 20U),
    /**< Timer counter 1 overflow interrupt */
    WES_TIMER_INT_OVERFLOW1_STATUS = (0x1U << 21U),
    /**< Timer counter 2 overflow interrupt */
    WES_TIMER_INT_OVERFLOW2_STATUS = (0x1U << 22U),
    /**< Timer counter 3 overflow interrupt */
    WES_TIMER_INT_OVERFLOW3_STATUS = (0x1U << 23U),
} Wes_TimerInterruptStatusType;

/** \brief WES APB Error interrupt status */
typedef enum {
    /**< Pwdata fatal error interrupt status */
    WES_APB_ERR_PWDAT_F_INT_STATUS = (0x1U << 9U),
    /**< Pwdata uncorrectable error interrupt status */
    WES_APB_ERR_PWDAT_U_INT_STATUS = (0x1U << 10U),
    /**< Pwdata correctable error interrupt status */
    WES_APB_ERR_PWDAT_C_INT_STATUS = (0x1U << 11U),
    /**< Pctrl0 uncorrectable error interrupt status */
    WES_APB_ERR_PCTRL0_INT_STATUS = (0x1U << 12U),
    /**< Pctrl1 uncorrectable error interrupt status */
    WES_APB_ERR_PCTRL1_INT_STATUS = (0x1U << 13U),
    /**< Puser uncorrectable error interrupt status */
    WES_APB_ERR_PUSER_INT_STATUS = (0x1U << 14U),
    /**< Paddr uncorrectable error interrupt status */
    WES_APB_ERR_PADDR_INT_STATUS = (0x1U << 15U),
} Wes_ApbErrInterruptStatusType;

/** \brief WES APB Error interrupt enable */
typedef enum {
    /**< Pwdata fatal error interrupt enable */
    WES_APB_ERR_PWDAT_F_INT_ENABLE = (0x1U << 1U),
    /**< Pwdata uncorrectable error interrupt enable */
    WES_APB_ERR_PWDAT_U_INT_ENABLE = (0x1U << 2U),
    /**< Pwdata correctable error interrupt enable */
    WES_APB_ERR_PWDAT_C_INT_ENABLE = (0x1U << 3U),
    /**< Pctrl0 uncorrectable error interrupt enable */
    WES_APB_ERR_PCTRL0_INT_ENABLE = (0x1U << 4U),
    /**< Pctrl1 uncorrectable error interrupt enable */
    WES_APB_ERR_PCTRL1_INT_ENABLE = (0x1U << 5U),
    /**< Puser uncorrectable error interrupt enable */
    WES_APB_ERR_PUSER_INT_ENABLE = (0x1U << 6U),
    /**< Paddr uncorrectable error interrupt enable */
    WES_APB_ERR_PADDR_INT_ENABLE = (0x1U << 7U),
} Wes_ApbErrInterruptEnableType;

/** \brief WES fusa interrupt config */
typedef struct {
    /**< Wes function configure check error */
    bool funcCfgIntEn;
    /**< Wes function clock monitor error */
    bool funcClkIntEn;
    /**< Sample value compare with reference value check */
    bool funcCompIntEn;
    /**< Digital mode DSE loopback check interrupt */
    bool funcDseLpIntEn;
    /**< Digital mode DSEL loopback check interrupt */
    bool funcDselLpIntEn;
    /**< Analog mode ASE loopback check interrupt */
    bool funcAseLpIntEn;
    /**< Timer0 PWM0/1 check interrupt */
    bool timer0Pwm01IntEn;
    /**< Timer0 PWM2/3 check interrupt */
    bool timer0Pwm23IntEn;
    /**< Timer1 PWM0/1 check interrupt */
    bool timer1Pwm01IntEn;
    /**< Timer1 PWM2/3 check interrupt */
    bool timer1Pwm23IntEn;
    /**< Timer0 function clock monitor interrupt */
    bool timer0ClkIntEn;
    /**< Timer1 function check monitor interrupt */
    bool timer1ClkIntEn;
    /**< Wes test mode check interrupt */
    bool testModeIntEn;
    /**< Selftest mode interrupt */
    bool selfTestModeIntEn;
    /**< Analog mode watchdog timeout or TID error */
    bool wdtToutIntEn;
    /**< Lockstep compare interrupt */
    bool lockstepIntEn;
    /**< External trigger diverse redundancy check error */
    bool externTrgIntEn;
    /**< Internal trigger diverse redundancy check error */
    bool internTrgIntEn;
} Wes_FusaInterruptConfigType;

/** \brief WES digital sample data */
typedef struct {
    /**< DATA0: bit23-bit0, DATA1~7: bit7-bit0 */
    uint32_t portData[WES_DIGITAL_SAMPLE_DATA_MAX];
} Wes_DigitalSamplePortType;

/** \brief WES analog sample data */
typedef struct {
    /**< SADC LUT index backward */
    uint8_t sadcTid;
    /**< SADC conversion data */
    uint16_t sadcConversionData;
} Wes_AnalogSampleDataType;

/** \brief WES timer counter config */
typedef struct {
    /**< Counter overflow value */
    uint16_t overflowValue;
    /**< Counter compare value */
    uint16_t compareValue;
    /**< PWM output polar */
    uint8_t pwmPolar;
    /**< PWM default polar */
    uint8_t pwmDefault;
    /**< Counter overflow interrupt enable */
    bool overflowIntEnable;
    /**< Counter compare interrupt enable */
    bool compareIntEnable;
    /**< Counter enable */
    bool counterEnable;
} Wes_TimerEventType;

/** \brief WES function control config */
typedef struct {
    /**< Function clock source select */
    Wes_ClockSourceType funcClkSel;

    /**< Enable function clock monitor */
    bool funcClkMonEn;

    /**< Function clock divider */
    Wes_FuncClockDividerType dividerForStabilization;
    /**< Stabilization time counter */
    uint16_t counterForStabilization;

    /**< WES work mode */
    Wes_WorkModeType workMode;
    /**< WES trigger mode */
    Wes_SampleTriggerType triggerSel;

    /**<  Digital Sample Config */

    /**< Digital sample enable */
    bool digitalEnable;
    /**< Stabilization time counter for DSEL */
    uint8_t counterForDselPortStabilization;
    /**< Digital sample trigger index */
    Wes_SampleTriggerIndexType digitalTriggerIndex;
    /**< Digital sample mode */
    Wes_SampleModeType digitalSampleMode;
    /**< Digital sample numbers when DSEL change one times */
    Wes_SampleNumberType digitalSampleNum;
    /**< Digital sample DSEL change number */
    Wes_DigitalSelectPortType digitalSelectPort;
    /**< Digital sample reference data */
    Wes_DigitalSamplePortType digitalRefData;
    /**< Digital sample compare enable */
    Wes_DigitalSamplePortType digitalDataCompareEnable;
    /**< Digital sample data record type */
    Wes_DigitalSampleDataUpdateType digitalSampleDataUpt;

    /**< Analog Sample Config */

    /**< Analog sample enable */
    bool analogEnable;
    /**< Analog sample trigger index */
    Wes_SampleTriggerIndexType analogTriggerIndex;
    /**< Analog sample mode */
    Wes_SampleModeType analogSampleMode;
    /**< Analog sample sadc LUT index forward */
    uint8_t analogSadcTid;
    /**< Analog sample sadc handshake WDT enable */
    bool analogWdtEnable;
    /**< Analog sample sadc handshake WDT timeout value */
    uint16_t wdtTimeoutCounter;
} Wes_FunctionCtrlType;

/** \brief WES timer control config */
typedef struct {
    /**< WES timer clock source */
    Wes_ClockSourceType clkSource;
    /**< WES timer clock divider */
    Wes_TimerClockDividerType clkDivider;
    /**< WES timer clock monitor enable */
    bool clkMonEn;
    /**< WES timer work mode */
    Wes_WorkModeType workMode;
    /**< WES timer counters config */
    Wes_TimerEventType counterEvent[WES_TIMER_COUNTER_MAX];
} Wes_TimerCtrlType;

/********************************************************************************************************
 *                                  Global Function Declarations *
 *******************************************************************************************************/
/**
 * @brief Sets the function control parameters for the WES.
 *
 * This function configures various registers of the WES IP based on the input
 * parameters provided in the `funcCtrl` structure. It includes settings for
 * functional clock monitoring, sample modes, trigger selections, work modes,
 * digital and analog enable/disable, reference data, comparison enable,
 * stabilization values, analog control, and analog watchdog timer.
 *
 * @param base The base address of the WES IP registers.
 * @param funcCtrl Pointer to a `Wes_FunctionCtrlType` structure containing the
 *        configuration parameters.
 *
 * @return `WES_OK` on successful configuration, or an error code indicating the
 *         specific failure.
 */
int32_t Wes_SetFunctionCtrl(uint32_t base, Wes_FunctionCtrlType *funcCtrl);

/**
 * @brief Fetches digital sample data from a specified base address and converts
 * it to a user-defined configuration format.
 *
 * This function reads digital sample data from three consecutive registers
 * starting from the given base address. The read data is then converted into a
 * user-defined configuration format using the helper function
 * Wes_DigitalRegToCfg.
 *
 * @param base The base address from which to read the digital sample data.
 * @param sampleData Pointer to a variable of type Wes_DigitalSamplePortType
 * that will hold the converted sample data.
 *
 * @return Returns WES_OK if the operation is successful.
 */
int32_t Wes_GetDigitalSampleData(uint32_t base,
                                 Wes_DigitalSamplePortType *sampleData);

/**
 * @brief This function retrieves the analog SADC (Sigma-Delta Analog-to-Digital
 * Converter) conversion data from the specified base address.
 *
 * @param base        The base address of the WES (Wireless Energy Sensor) IP
 * block.
 * @param sampleData  Pointer to a structure of type Wes_AnalogSampleDataType
 * where the SADC conversion data and TID (Tag Identifier) will be stored.
 *
 * @return Returns WES_OK if the function successfully retrieves the conversion
 * data.
 *
 * @details The function reads the control register of the WES analog block at
 * the given base address plus the offset WES_ANA_CTL_OFF. It then extracts the
 *          SADC TID and conversion data from the read register value using
 * bitwise operations defined by GFV_WES_ANA_CTL_SADC_TID_BW and
 * GFV_WES_ANA_CTL_SADC_DATA macros, respectively. The extracted values are
 * stored in the provided sampleData structure.
 */
int32_t Wes_GetAnalogSadcConversionData(uint32_t base,
                                        Wes_AnalogSampleDataType *sampleData);

/**
 * @brief Set the control parameters for a timer.
 *
 * This function configures the timer based on the provided control parameters.
 * It sets the clock monitoring enable, clock enable, clock source, work mode,
 * clock divider, counter enable, compare interrupt enable, and overflow
 * interrupt enable for the specified timer.
 *
 * @param base        Base address of the timer module.
 * @param timer       The type of timer to configure.
 * @param timerCtrl   Pointer to a structure containing the timer control
 * parameters.
 *
 * @return Returns WES_OK if the timer control parameters were set successfully,
 *         otherwise returns an error code.
 */
int32_t Wes_SetTimerCtrl(uint32_t base, Wes_TimerType timer,
                         Wes_TimerCtrlType *timerCtrl);

/**
 * @brief Get the interrupt status of a specific timer.
 *
 * This function retrieves the interrupt status of a specified timer by reading
 * the corresponding status register. The interrupt status is masked to extract
 * only the relevant bits from the register.
 *
 * @param base The base address of the timer module.
 * @param timer The type of timer to check the interrupt status for. This should
 * be of type Wes_TimerType, which enumerates the different timers.
 *
 * @return A 32-bit value representing the interrupt status of the specified
 * timer. The returned value contains only the relevant bits from the status
 *         register, specifically the bits located between 16 and 23
 * (inclusive).
 */
uint32_t Wes_GetTimerInterruptStatus(uint32_t base, Wes_TimerType timer);

/**
 * @brief Clears the interrupt status for a specified timer.
 *
 * This function reads the interrupt status register for the given timer,
 * effectively clearing the interrupt by writing back the same value.
 *
 * @param base The base address of the timer module.
 * @param timer The type of timer to clear the interrupt status for.
 *              This should be of type Wes_TimerType, which is an enumeration
 *              representing the different timers available.
 *
 * @return WES_OK upon successful completion of the operation.
 */
int32_t Wes_ClearTimerInterruptStatus(uint32_t base, Wes_TimerType timer);

/**
 * @brief Get the FUSA interrupt status from the specified base address.
 *
 * This function reads the interrupt status register of the FUSA
 * module, which is located at an offset from the given base address.
 * It then masks the upper 16 bits of the register value and returns this masked
 * value.
 *
 * @param base The base address of the FUSA module.
 * @return The masked interrupt status (upper 16 bits of the interrupt status
 * register).
 */
uint32_t Wes_GetFusaInterruptStatus(uint32_t base);

/**
 * @brief Clears the FUSA interrupt status.
 *
 * This function reads the interrupt status register of the FUSA
 * module, effectively acknowledging and clearing the current interrupt status.
 *
 * @param base The base address of the FUSA module's register space.
 *
 * @return Always returns WES_OK indicating success.
 */
int32_t Wes_ClearFusaInterruptStatus(uint32_t base);

/**
 * @brief       Gets the loopback check error status.
 *
 * @param       base  The base address of the Wes IP block.
 *
 * @return      Returns the loopback check error status.
 *              The status is read from the register at (base + LP_CHECK_OFF).
 */
uint32_t Wes_GetLoopbackCheckErrorStatus(uint32_t base);

/**
 * @brief Clears the loopback check error status bits in the specified register.
 *
 * This function reads the loopback check status register, clears the specified
 * error status bits, and writes the updated value back to the register.
 *
 * @param base The base address of the hardware register block.
 * @return WES_OK upon successful completion of the operation.
 */
int32_t Wes_ClearLoopbackCheckErrorStatus(uint32_t base);

/**
 * @brief Set the FUSA interrupt configuration.
 *
 * This function reads the current interrupt configuration from the specified
 * base address, clears the relevant interrupt enable bits, and then sets the
 * bits according to the provided configuration structure. The updated
 * configuration is then written back to the hardware registers.
 *
 * @param base The base address of the WES registers.
 * @param fusaInt Pointer to a structure containing the interrupt configuration.
 *
 * @return Returns WES_OK if the configuration is set successfully.
 */
int32_t Wes_SetFusaInterrupt(uint32_t base,
                             Wes_FusaInterruptConfigType *fusaInt);

/**
 * @brief Set APB Error interrupt enable.
 *
 * @param base The base address of the WES registers.
 * @param intType Each bit represent one interrupt type, defined in
 * Wes_ApbErrInterruptEnableType.
 * @param enable Interrupt enable or not.
 *
 * @return Returns WES_OK if the configuration is set successfully.
 */
int32_t Wes_ApbErrorInterruptEnable(uint32_t base, uint32_t intType,
                                    bool enable);

/**
 * @brief Clear APB Error interrupt status.
 *
 * @param base The base address of the WES registers.
 * @param intType Each bit represent one interrupt status, defined in
 * Wes_ApbErrInterruptStatusType.
 *
 * @return Returns WES_OK if the configuration is set successfully.
 */
int32_t Wes_ClearApbErrorInterruptStatus(uint32_t base, uint32_t statusType);

#endif /* WES_H */
/* End of file */
